WPF ships with many controls that allow you to capture or display simple blurbs of textual data, including Label, TextBox, TextBlock, and PasswordBox. These controls are useful, but some WPF applications require the use of sophisticated, highly formatted text data, similar to what you might find in an Adobe PDF file. The Documents API of WPF provides such functionality; however, it uses the XML Paper Specification (XPS) format rather than the PDF file format .
You can use the Documents API to construct a print-ready document by leveraging several classes from the System.Windows.Documents namespace. Here you will find a number of types that represent pieces of a rich XPS document, such as List, Paragraph, Section, Table, LineBreak, Figure, Floater, and Span.
Formally speaking, the items you add to a XPS document belong to one of two broad categories: block elements and inline elements. This first category, block elements, consists of classes that extend the System.Windows.Documents.Block base class. Examples of block elements include List, Paragraph, BlockUIContainer, Section, and Table. You use classes from this category to group together other content (e.g., a list containing paragraph data, and a paragraph containing sub paragraphs for different text formatting).
The second category, inline elements, consists of classes that extend the System.Windows.Documents.Inline base class. You nest inline elements within another block item (or possibly within another inline element inside a block element). Some common inline elements include Run, Span, LineBreak, Figure, and Floater.
These classes possess names that you might encounter when building a rich document with a professional editor. As with any other WPF control, you can configure these classes in XAML or through code. Therefore, you can declare an empty <Paragraph> element that is populated at runtime (you’ll see how to do such tasks in this example).
You might think you can simply place inline and block elements directly into a panel container such as a Grid; however, you need to wrap them in a <FlowDocument> element or a <FixedDocument> element.
It is ideal to place items in a FlowDocument when you wish to let your end user change the way the data is presented on the computer screen. The user can do this by zooming text or changing how the data is presented (e.g., a single long page or a pair of columns). You’re better off using FixedDocument for true print-ready (WYSIWYG), unchangeable document data.
For this example, you will only concern yourself with the FlowDocument container. Once you insert inline and block items to your FlowDocument, the FlowDocument object is placed in one of four specialized XPS-aware layout managers, listed in Table 28-4.
Table 28-4. XPS Control Layout Managers
Panel Control | Meaning in Life |
---|---|
FlowDocumentReader | Displays data in a FlowDocument and adds support for zooming, searching, and content layout in various forms. |
FlowDocumentScrollViewer | Displays data in a FlowDocument; however, the data is presented as a single document viewed with scrollbars. This container does not support zooming, searching, or alternative layout modes. |
RichTextBox | Displays data in a FlowDocument and adds support for user editing. |
FlowDocumentPageViewer | Displays the document page-by-page, one page at a time. Data can also be zoomed, but not searched. |
The most feature-rich way to display a FlowDocument is to wrap it within a FlowDocumentReader manager. When you do this, the user can alter the layout, search for words in the document, and zoom in on the data using the provided UI. The one limitation of this container (as well as of FlowDocumentScrollViewer and FlowDocumentPageViewer) is that the content you display with it is read only. However, if you do want to allow the end user to enter new information to the FlowDocument, you can wrap it in a RichTextBox control.